var express = require('express');
var router = express.Router();
const { videoModel, usersModel, commentModel, childCommentModel } = require("../module/model")
const path = require('path');
const OSS = require('ali-oss');
const fs = require("fs");
const ffmpeg = require("fluent-ffmpeg");

// API

// 添加视频
router.post("/addVideo", (req, res) => {
    const { userId, videoUrl, describe } = req.body
    let videoObj = {
        videoUrl: videoUrl, // 视频链接
        userId: userId, // 用户ID
        thumbsUp: 0, // 点赞
        describe: describe, // 描述
        forward: 0, // 转发
        collect: 0, // 收藏
    }
    videoModel.create(videoObj)
    res.send({
        code: 200,
        message: "视频添加成功"
    })
})
// 添加父级评论
router.post("/addComment", (req, res) => {
    const { userId, videoId, content, created_at } = req.body
    // console.log(videoId);

    const commentObj = {
        userId: userId, // 用户id
        videoId: videoId, // 视频id
        content: content, // 内容
        created_at: created_at, // 评论时间
        updated_at: "", // 评论更新时间
        like_count: 0, // 点赞量（可扩展）
        is_deleted: false // 是否删除
    }
    commentModel.create(commentObj)
    res.send({
        code: 200
    })
})
// 添加子级评论
router.post("/CommentChildAdd", (req, res) => {
    const { userId, content, created_at, parent_comment_id, parent_id, videoId } = req.body
    const commentObj = {
        userId: userId, // 用户id
        content: content, // 内容
        videoId: videoId, // 视频id
        parent_comment_id: parent_comment_id, // 父级ID
        created_at: created_at, // 评论时间
        updated_at: "", // 评论更新时间
        like_count: 0, // 点赞量（可扩展）
        is_deleted: false, // 是否删除
        parent_id: parent_id // 给子级评论的id
    }
    childCommentModel.create(commentObj)
    res.send({
        code: 200
    })
})
// 查找当前视频评论数量
router.get("/getComment", async (req, res) => {
    const { videoId } = req.query

    //  某条视频的总评论
    const commentCount = await commentModel.countDocuments({ videoId }) +
        await childCommentModel.countDocuments({ videoId });
    console.log(commentCount);
    
    res.send({
        code: 200,
        commentCount
    })
})
// 查找当前视频评论数据
router.post("/getCommentList", async (req, res) => {
    const { videoId } = req.body;
    try {
        // 查找父级表
        const commentList = await commentModel.find({ videoId })
            .populate("userId")
            .lean();

        res.send({
            code: 200,
            commentList,
        })
    } catch (error) {
        console.error(error);
        res.status(500).send({
            code: 500,
            message: '服务器内部错误'
        });
    }
})
// 查找当前视频父评论下的子评论
router.post("/getChildComments", async (req, res) => {
    const { parentCommentIds, page = 1, pageSize = 3 } = req.body; // 每次加载3条子评论
    const skip = (page - 1) * pageSize;

    try {
        // 查找与父评论相关的子评论
        const childComments = await childCommentModel.find({ parent_comment_id: { $in: parentCommentIds } })
            .skip(skip)
            .limit(pageSize)
            .populate("userId")
            .lean();

        // 获取回复的子评论的详细数据，每个子评论有一个 parent_id
        const replyToCommentIds = childComments
            .filter(comment => comment.parent_id)
            .map(comment => comment.parent_id);

        let replies = [];
        if (replyToCommentIds.length > 0) {
            // 查找所有回复的子评论
            replies = await childCommentModel.find({ _id: { $in: replyToCommentIds } })
                .populate("userId")
                .lean();
        }

        // 将回复的评论映射为一个键值对，方便后续合并
        const repliesMap = replies.reduce((acc, reply) => {
            acc[reply._id] = reply;
            return acc;
        }, {});

        // 将回复的评论合并到原始的子评论中
        const childCommentsWithReplies = childComments.map(comment => {
            if (comment.parent_id && repliesMap[comment.parent_id]) {
                comment.replyToCommentData = repliesMap[comment.parent_id];
            }
            return comment;
        });

        // 根据 parentCommentId 分组子评论
        const groupedChildComments = childCommentsWithReplies.reduce((acc, child) => {
            if (!acc[child.parent_comment_id]) acc[child.parent_comment_id] = [];
            acc[child.parent_comment_id].push(child);
            return acc;
        }, {});

        // 判断是否有更多子评论
        const hasMore = childCommentsWithReplies.length === pageSize;

        // 返回子评论数据，按父评论 ID 分组
        res.send({
            code: 200,
            childComments: groupedChildComments,
            hasMore: hasMore
        });
    } catch (error) {
        console.error(error);
        res.status(500).send({
            code: 500,
            message: '服务器内部错误'
        });
    }
});

// 获取视频
router.get("/getVideo", async (req, res) => {
    const page = parseInt(req.query.page) || 1; // 获取前端传入的页码，默认为 1
    const pageSize = 3; // 每页返回 5 条数据
    const skip = (page - 1) * pageSize; // 计算跳过的数据条数

    try {
        // 2.如果没有命中，则查询视频数据，并进行分页
        const videoList = await videoModel.aggregate([
            { $skip: skip },
            { $limit: pageSize },
            {
                $lookup: {
                    from: 'users', // 假设关联的用户表名是 'users'
                    localField: 'userId',
                    foreignField: '_id',
                    as: 'users'
                }
            },
            { $unwind: { path: "$user", preserveNullAndEmptyArrays: true } } // 处理关联为空的情况
        ]);

        // 计算总记录数
        const totalCount = await videoModel.countDocuments();
        const totalPages = Math.ceil(totalCount / pageSize);

        // 构造响应数据
        const responseData = {
            code: 200,
            videoList,
            // totalCount,   // 总记录数
            totalPages, // 总页数
            // currentPage: page  // 当前页
        };

        // 4. 发送响应
        res.send(responseData);
    } catch (error) {
        console.error("Error fetching video data:", error);
        res.status(500).send({
            code: 500,
            message: "服务器错误"
        });
    }
})

// SDK 配置

const client = new OSS({
    // 从环境变量中获取访问凭证。运行本代码示例之前，请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
    accessKeyId: "LTAI5tGtQ5w7GZ5wSBcuVXhK",
    accessKeySecret: "xd5Vhsx4epTM8Czc8WiBWPuVCSrvnG",
    // yourRegion填写Bucket所在地域。以华东1（杭州）为例，Region填写为oss-cn-hangzhou。
    region: 'oss-cn-beijing',
    authorizationV4: true,
    // yourBucketName填写Bucket名称。
    bucket: 'yang-voice-img-node',
});


// 访问全家桶中的数据
// async function list() {
//     // 不带任何参数，默认最多返回100个文件。
//     const result = await client.list();
//     console.log(result);
// }
// list()

// 自定义请求头
const headers = {
    // 指定Object的存储类型。
    'x-oss-storage-class': 'Standard',
    // 指定Object的访问权限。
    'x-oss-object-acl': 'private',
    // 通过文件URL访问文件时，指定以附件形式下载文件，下载后的文件名称定义为example.txt。
    // 'Content-Disposition': 'attachment; filename="example.txt"',
    // 设置Object的标签，可同时设置多个标签。
    // 'x-oss-tagging': 'Tag1=1&Tag2=2',
    // 指定PutObject操作时是否覆盖同名目标Object。此处设置为true，表示禁止覆盖同名Object。
    // 'x-oss-forbid-overwrite': 'true',
};
// 上传视频到桶及数据库中中
router.post("/uploadVoice", async (req, res) => {
    try {
        const { userId, filePath, describe } = req.body
        // const filePath = `http://localhost:3000/Yjr/upload/5.mp4`
        // const userId = "676aa190d24f70b283bdf726"
        // const describe = "祝眉目舒展，顺问冬安"

        const fileName = path.basename(filePath);
        const norPath = path.resolve(`./upload/${fileName}`);

        // 设定压缩后的视频路径
        const compressedFilePath = path.resolve(`./upload/compressed_${fileName}`);
        console.log(norPath, compressedFilePath);
        
        // 压缩视频
        await compressVideo(norPath, compressedFilePath)

        // 上传压缩后的文件到阿里云 OSS
        // 未压缩文件地址
        const originalOssPath = `voice/original/${fileName}`
        // 压缩文件地址
        const compressedOssPath = `voice/compressed/compressed_${fileName}`

        // 填写OSS文件完整路径和本地文件的完整路径。OSS文件完整路径中不能包含Bucket名称。
        // 如果本地文件的完整路径中未指定本地路径，则默认从示例程序所属项目对应本地路径中上传文件。
        // 获取文件的名称（不包含路径）

        // 原视频
        const original = await client.put(originalOssPath, norPath
            // 自定义headers
            , { headers }
        );
        // 压缩过后的视频
        const compressed = await client.put(compressedOssPath, compressedFilePath
            // 自定义headers
            , { headers }
        );

        let videoObj = {
            videoUrl: [original.url, compressed.url], // 视频链接
            userId: userId, // 用户ID
            describe: describe, // 描述
        }

        videoModel.create(videoObj)

        // 删除本地临时文件
        if (fs.existsSync(norPath)) fs.unlinkSync(norPath);
        if (fs.existsSync(compressedFilePath)) fs.unlinkSync(compressedFilePath);

        res.send({
            code: 200,
            message: "原视频及视频压缩并上传成功到数据库"
        })
    } catch (err) {
        console.error('上传失败:', err);
    }
})

// 压缩视频的函数
async function compressVideo(inputFilePath, outputFilePath) {
    return new Promise((resolve, reject) => {
        ffmpeg(inputFilePath)
            .output(outputFilePath)  // 输出到本地文件
            // .videoCodec('libx264')   // 使用 H.264 编码
            .videoCodec('libvpx')   // 使用 libvpx 编码
            // .audioCodec('aac')       // 使用 AAC 编码
            .audioCodec('libvorbis')       // 使用 libvorbis 编码
            .videoBitrate(1000)      // 设置比特率
            // .size('854x480')        // 设置视频分辨率
            .on('end', () => {
                console.log('视频压缩完成');
                resolve();
            })
            .on('error', (err) => {
                console.error('视频压缩失败:', err);
                reject(err);
            })
            .run();
    });
}

module.exports = router;
